﻿using System.Diagnostics;
using System.Runtime.Serialization;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using Game.ExtensibleObjects;
using Game.ResourceLocator;

namespace Game.Types
{
    public interface IMapItemType
    {
        ImageSource Picture { get; }

        string Name { get; }
    }
    
    /// <summary>
    /// The base class for everything that can be placed on a map field.
    /// </summary>
    [DataContract(Namespace="game")]
    public abstract class MapItemType :
        ExtensibleObject, IMapItemType, IHasUrl
    {
        [DataMember(Name="Url")]
        public string _Url;

        RuntimeExtensionFactoryCollection _RuntimeExtensionFactories;
        string _Name;
        string _Description;
        string _InfoText;
        ImageSource _Picture;
        
        internal MapItemType()
        {
        }
        
        [OnDeserialized]
        public void OnDeserialized(StreamingContext c)
        {
            object obj = GameResourceLocator.Get(Url);
            var t = obj as MapItemType;
            if (t != null)
            {
                _Name = t.Name;
                _Description = t.Description;
                _InfoText = t.InfoText;
                _Picture = t.Picture;
                _RuntimeExtensionFactories = t.RuntimeExtensionFactories;

                Debug.Assert(_Name != null);
                Debug.Assert(_Name.Length > 0);
            }
        }

        protected MapItemType(MapItemTypeBuilder builder)
            : base(builder.Extensions.GetReadOnly())
        {
            _Name = builder.Name;
            _Picture = builder.Picture;
            _Description = builder.Description;
            _InfoText = builder.InfoText;
            _Url = builder.Url;
            _extensions = builder.Extensions.GetReadOnly();
            _RuntimeExtensionFactories = builder.RuntimeExtensionFactories;
            
            Debug.Assert(_Name != null);
            Debug.Assert(_Name.Length > 0);
        }
        
        public string Name
        {
            get { return _Name; }
        }
        
        public string Url
        {
            get { return _Url; }
            set { _Url=value; }
        }
        
        public string Description
        {
            get { return _Description; }
        }
        
        public ImageSource Picture
        {
            get { return _Picture; }
        }
        
        public string InfoText
        {
            get { return _InfoText; }
        }

        public RuntimeExtensionFactoryCollection RuntimeExtensionFactories
        {
            get { return _RuntimeExtensionFactories; }
        }

    }
    
    public abstract class MapItemTypeBuilder 
    {
        readonly ExtensionCollection _Extensions;
        readonly RuntimeExtensionFactoryCollection _RuntimeExtensionFactories;

        public string Name { get; set; }
        public string Description {get; set;}
        public string InfoText {get; set;}
        public ImageSource Picture { get; set; }

        protected MapItemTypeBuilder()
        {
            _Extensions = new ExtensionCollection();
            _RuntimeExtensionFactories = new RuntimeExtensionFactoryCollection();
        }

        public RuntimeExtensionFactoryCollection RuntimeExtensionFactories
        {
            get { return _RuntimeExtensionFactories; }
        }

        public ExtensionCollection Extensions
        {
            get { return _Extensions; }
        }

        public abstract string TypeName
        {
            get;
        }
        
        public string Url
        {
            get
            {
                return TypeName + ":" + Name;
            }
        }

        public override string ToString()
        {
            return Name;
        }
    }
}
